Home:ALL Converter>Is it dangerous to have a cast operator on a unique_ptr?

Is it dangerous to have a cast operator on a unique_ptr?

Ask Time:2012-06-22T04:38:17         Author:hunter

Json Formatter

We have an extensive code base which currently uses raw pointers, and I'm hoping to migrate to unique_ptr. However, many functions expect raw pointers as parameters and a unique_ptr cannot be used in these cases. I realize I can use the get() method to pass the raw pointer, but this increases the number of lines of code I have to touch, and I find it a tad unsightly. I've rolled my own unique_ptr which looks like this:

template <class T>
class my_unique_ptr: public unique_ptr <T>
{
  public:

    operator T*() { return get(); };
};

Then every time I provide a my_unique_ptr to a function parm which expects a raw pointer, it automagically turns it into the raw pointer.

Question: Is there something inherently dangerous about doing this? I would have thought this would have been part of the unique_ptr implementation, so I'm presuming its omission is deliberate - does anyone know why?

Author:hunter,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/11146354/is-it-dangerous-to-have-a-cast-operator-on-a-unique-ptr
Attila :

It is the same as invoking the get on the unique_ptr<>, but it will be done automatically. You will have to make sure the pointer is not stored/used after the function returns (as unique_ptr<> will delete it when its lifetime ends).\n\nAlso make sure you don't call delete (even indirectly) on the raw pointer. \n\nYet another thing to make sure is that you do not create another smart pointer that takes ownership of the pointer (e.g. another uniqe_ptr<>) -- see delete note above\n\nThe reason for unique_ptr<> not doing the conversion for you automatically (and have you call get() explicitly) is to ensure you have control over when you access the raw pointer (to avoid the above issues that could happen silently otherwise)",
2012-06-21T20:44:24
John Dibling :

The main \"danger\" in providing an implicit conversion operator (to a raw pointer) on a unique_ptr stems from the fact that unique_ptr is supposed to model single-ownership semantics. This is also why it's not possible to copy a unique_ptr, but it can be moved.\n\nConsider an example of this \"danger\":\n\nclass A {};\n\n/* ... */\n\nunique_ptr<A> a(new A);\n\nA* a2 = a;\nunique_ptr<A> a3(a2);\n\n\nNow two unique_ptrs model single-ownership semantics over the object pointed to, and the fate of the free world -- nay, the universe -- hangs in the balance.\n\nOK, I'm being a bit dramatic, but that's the idea.\n\nAs far as workarounds go, I would normally just call .get() on the pointer and be done with it, being careful to recognize a lack of ownership on what I just got().\n\nGiven that you have a large, legacy code-base that you are trying to migrate to using unique_ptr, I think your conversion wrapper is fine -- but only assuming you and your co-workers don't make mistakes in the future when maintaining this code. If that is a possibility you find likely (and I normally would because I'm paranoid), I would try to retrofit all existing code to call .get() explicitly instead of providing an implicit conversion. The compiler will happily find all the instances for you where this change needs to be made.",
2012-06-22T13:06:41
Mooing Duck :

There's a lot of ugly things that can happen on accident with implicit conversions, such as this:\n\nstd::unique_ptr<resource> grab_resource() \n{return std::unique_ptr<resource>(new resource());}\n\nint main() {\n resource* ptr = grab_resource(); //compiles just fine, no problem\n ptr->thing(); //except the resource has been deallocated before this line\n return 0; //This program has undefined behavior.\n}\n",
2012-06-21T23:09:23
yy